package dark

import (
	"fmt"
	"sort"
)

type List[T any] []T

var (
	SortLen = func(a Str, b Str) bool {
		return a.Len() > b.Len()
	}
)

func (list List[T]) Join(sep ...string) Str {
	e := Str("")
	for _, i := range list {
		if e != "" && sep != nil {
			e += Str(sep[0])
		}
		e += Str(fmt.Sprint(i))
	}
	return e
}

func (list List[T]) AsAny() (fs List[any]) {
	for _, i := range list {
		fs = append(fs, i)
	}
	return
}

func (list List[T]) Sort(by func(l, r T) bool) List[T] {
	sort.Slice(list, func(i, j int) bool {
		return by(list[i], list[j])
	})
	return list
}

func (list List[T]) Add(i ...T) List[T] {
	return append(list, i...)
}

func (list List[T]) Every(e func(no int, i T)) List[T] {
	for ix, val := range list {
		e(ix, val)
	}
	return list
}

func (list List[T]) Any(e func(no int, i T) bool) (o T) {
	for ix, val := range list {
		if e(ix, val) {
			return val
		}
	}
	return
}

func (list List[T]) Count() int {
	return len(list)
}

func (list List[T]) Nth(i int) T {
	if i < 0 {
		i = list.Count() + i
	}
	return list[i]
}

func (list List[T]) Contains(i T) bool {
	return list.In(i)
}

func (list List[T]) In(i T, testFunc ...func(compareItem, item T) bool) bool {
	if testFunc != nil {
		for _, v := range list {
			if testFunc[0](i, v) {
				return true
			}
		}
		return false
	} else {
		for _, v := range list {
			// fmt.Println(v, i)
			if fmt.Sprint(v) == fmt.Sprint(i) {
				return true
			}
		}
		return false
	}
}

func (list List[T]) Find(key func(ix int, item T) bool) (found T) {
	for i, v := range list {
		if key(i, v) {
			return v
		}
	}
	return
}

func (list List[T]) FindFunc(key func(ix int, item T) bool) (call func(item T) T) {
	call = func(item T) (found T) {
		for i, v := range list {
			if key(i, v) {
				return v
			}
		}
		return
	}
	return call
}
